﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Globalization;

namespace Microsoft.International.Formatters
{

    /// <summary>
    /// Italian (it-IT) formatter
    /// </summary>
    [FormatCultureInfoAttribute("it-IT")]
    internal sealed class ITStdFormatter : EuropeFormatter
    {

        /// <summary>
        /// Returns the Decimal value to String.
        /// </summary>
        /// <param name="num">Value to translate.</param>
        /// <returns>Returns the specified Decimal value to String.</returns>
        /// <remarks>Abstract method, must be implemented.</remarks>
        internal override String ConvertToLocalizedText(Decimal num)
        {
            String strMoins = String.Empty;
            Int32 value = (Int32)num; // TODO: Supprimer cette ligne
            if (value < 0)
            {
                strMoins = "menos ";
                if (value == Int32.MinValue)
                {
                    strMoins += "dosmilmilliones";
                    value += 2000000000;
                }
                value = Math.Abs(value);
            }

            return strMoins + BillionToString(value);
        }

        /// <summary>
        /// Convert units (Int32 format) to String format.
        /// </summary>
        /// <param name="value">Value to convert</param>
        /// <returns>Returns a text which represents the specified value</returns>
        private String UnitToString(Int32 value)
        {
            if (value > 9)
                return TenToString(value);

            String result = String.Empty;

            switch (value.ToString(new CultureInfo("it-IT")))
            {
                case "0": result = "zero"; break;
                case "1": result = "uno"; break;
                case "2": result = "due"; break;
                case "3": result = "tre"; break;
                case "4": result = "quattro"; break;
                case "5": result = "cinque"; break;
                case "6": result = "sei"; break;
                case "7": result = "sette"; break;
                case "8": result = "otto"; break;
                case "9": result = "nove"; break;
            }

            return result;
        }

        /// <summary>
        /// Convert tens (Int32 format) to String format.
        /// </summary>
        /// <param name="value">Value to convert</param>
        /// <returns>Returns a text which represents the specified value</returns>
        private String TenToString(Int32 value)
        {
            if (value < 10)
                return UnitToString(value);
            else if (value > 99)
                return HundredToString(value);

            String result = String.Empty;

            switch (value)
            {
                case 10: result = "dieci"; break;
                case 11: result = "undici"; break;
                case 12: result = "dodici"; break;
                case 13: result = "tredici"; break;
                case 14: result = "quattordici"; break;
                case 15: result = "quindici"; break;
                case 16: result = "sedici"; break;
                case 17: result = "diciassette"; break;
                case 18: result = "diciotto"; break;
                case 19: result = "diciannove"; break;
                case 20: result = "venti"; break;
                case 21: result = "ventuno"; break;
                case 22: result = "ventidue"; break;
                case 23: result = "ventitre"; break;
                case 24: result = "ventiquattro"; break;
                case 25: result = "venticinque"; break;
                case 26: result = "ventisei"; break;
                case 27: result = "ventisette"; break;
                case 28: result = "ventotto"; break;
                case 29: result = "veintinueve"; break;

                case 30: result = "trenta"; break;
                case 40: result = "quaranta"; break;
                case 50: result = "cinquanta"; break;
                case 60: result = "sessanta"; break;
                case 70: result = "settanta"; break;
                case 80: result = "ottanta"; break;
                case 90: result = "novanta"; break;
                default:
                    String ten = TenToString(value.GetTen());
                    String unit = UnitToString(value.GetUnit());
                    if (unit[0].IsVowel() & ten[ten.Length - 1].IsVowel())
                        ten = ten.Substring(0, ten.Length - 1);
                    result = String.Format(new CultureInfo("it-IT"), "{0}{1}", ten, unit);
                    break;
            }

            return result;
        }

        /// <summary>
        /// Convert hundreds (Int32 format) to String format.
        /// </summary>
        /// <param name="value">Value to convert</param>
        /// <returns>Returns a text which represents the specified value</returns>
        private String HundredToString(Int32 value)
        {
            if (value < 100)
                return TenToString(value);
            else if (value > 999)
                return ThousandToString(value);

            Int32 reste = 0;
            Int32 centaine = System.Math.DivRem(value, 100, out reste);

            String ciento = String.Empty;

            switch (centaine)
            {
                case 1: ciento = "cento"; break;
                case 2: ciento = "duecento"; break;
                case 3: ciento = "trecento"; break;
                case 4: ciento = "quattrocento"; break;
                case 5: ciento = "cinquecento"; break;
                case 6: ciento = "seicento"; break;
                case 7: ciento = "settecento"; break;
                case 8: ciento = "ottocento"; break;
                case 9: ciento = "novecento"; break;
            }

            if (reste == 0)
                return ciento;
            else
            {
                String ten = TenToString(reste);
                if (ten[0].IsVowel() & ciento[ciento.Length - 1].IsVowel())
                    ciento = ciento.Substring(0, ciento.Length - 1);

                return String.Format(new CultureInfo("it-IT"), "{0}{1}", ciento, ten);

            }
        }

        /// <summary>
        /// Convert thousands (Int32 format) to String format.
        /// </summary>
        /// <param name="value">Value to convert</param>
        /// <returns>Returns a text which represents the specified value</returns>
        private String ThousandToString(Int32 value)
        {
            if (value < 1000)
                return HundredToString(value);
            else if (value > 999999)
                return MillionToString(value);

            Int32 reste = 0;
            Int32 millier = System.Math.DivRem(value, 1000, out reste);

            String strMillier = "mille";
            if (millier > 1)
                strMillier = String.Format(new CultureInfo("it-IT"), "{0}mila", HundredToString(millier));

            if (reste == 0) return strMillier;
            return String.Format(new CultureInfo("it-IT"), "{0}{1}", strMillier, HundredToString(reste));
        }

        /// <summary>
        /// Convert millions (Int32 format) to String format.
        /// </summary>
        /// <param name="value">Value to convert</param>
        /// <returns>Returns a text which represents the specified value</returns>
        private String MillionToString(Int32 value)
        {
            if (value < 1000000)
                return HundredToString(value);

            Int32 reste = 0;
            Int32 millions = System.Math.DivRem(value, 1000000, out reste);

            String strMillions = "unmilione";

            if (millions > 1)
                strMillions = String.Format(new CultureInfo("it-IT"), "{0}milioni", ThousandToString(millions));

            if (reste > 0)
                strMillions = String.Format(new CultureInfo("it-IT"), "{0}{1}", strMillions, ThousandToString(reste));

            return strMillions;
        }

        /// <summary>
        /// Convert billions (Int32 format) to String format.
        /// </summary>
        /// <param name="value">Value to convert</param>
        /// <returns>Returns a text which represents the specified value</returns>
        private String BillionToString(Int32 value)
        {
            if (value < 1000000000)
                return MillionToString(value);

            Int32 reste = 0;
            Int32 millions = System.Math.DivRem(value, 1000000000, out reste);

            String strMillions = "unmiliardo";

            if (millions > 1)
                strMillions = String.Format(new CultureInfo("it-IT"), "{0}miliardo", ThousandToString(millions));

            if (reste > 0)
                strMillions = String.Format(new CultureInfo("it-IT"), "{0}{1}", strMillions, ThousandToString(reste));

            return strMillions;
        }

    }

}